package com.tutos.ui.student;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.inject.Inject;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;

import com.tutos.dao.EstudianteDAO;
import com.tutos.dao.MensajeDAO;
import com.tutos.dao.MonitorDAO;
import com.tutos.model.Estudiante;
import com.tutos.model.Mensaje;
import com.tutos.model.Monitor;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.OptionGroup;
import com.vaadin.ui.Table;
import com.vaadin.ui.TextField;
import com.vaadin.ui.Window;
import com.vaadin.ui.Window.Notification;

// Student messages
public class StudentMessages extends CustomComponent implements
		Property.ValueChangeListener {

	private static final long serialVersionUID = 1L;

	private GridLayout mainLayout;
	private HorizontalLayout horizontalLayout_1;
	private Button btnSend;

	private Table tableContacts;
	private Label lblMessages2;
	private GridLayout gridLayout_2;
	private Button btnMessages;
	private OptionGroup optionMessages;
	private Table tableMessages;
	private Label lblMessage1;

	private ArrayList<String> correosSeleccionados = new ArrayList<String>();

	// DAOs necesarios
	private EstudianteDAO est;
	private MonitorDAO mon;
	private MensajeDAO mensajeDAO;

	// Containers necesarios
	private IndexedContainer monitorData;
	private IndexedContainer containerMensajesRecibidos;
	private IndexedContainer containerMensajesEnviados;

	private Subject currentUser = SecurityUtils.getSubject();
	private Estudiante estudianteActual;

	private static String[] fieldnames = { "Monitor id", "Nombre", "Teléfono",
			"Ubicación", "Email" };

	private static String[] fieldMensajesRecibidos = new String[] { "Asunto",
			"De", "Fecha enviado", "Contenido", "CorreoRemitente" };

	private static String[] fieldMensajesEnviados = new String[] { "Asunto",
			"Para", "Fecha enviado", "Contenido" };

	private static String[] visibleCols = new String[] { "Nombre", "Teléfono",
			"Ubicación", "Email" };

	private static String[] visiblecolsMensajesEnviados = new String[] {
			"Asunto", "Para", "Fecha enviado" };

	private static String[] visiblecolsMensajesRecibidos = new String[] {
			"Asunto", "De", "Fecha enviado" };

	@Inject
	public StudentMessages(EstudianteDAO est, MonitorDAO mon,
			MensajeDAO mensajeDAO) {
		this.est = est;
		this.mon = mon;
		this.mensajeDAO = mensajeDAO;
		buildMainLayout();
		initTable();
		initTableMessages();
		setCompositionRoot(mainLayout);
		initFilteringControls();
	}

	private void initTableMessages() {
		estudianteActual = est.getEstudianteByCorreo((String) currentUser
				.getSession().getAttribute("username"));

		List<Mensaje> mensajesRecibidos = mensajeDAO
				.getAllRecibidos(estudianteActual);

		List<Mensaje> mensajesEnviados = mensajeDAO
				.getAllEnviados(estudianteActual);

		containerMensajesRecibidos = loadMensajesRecibidos(mensajesRecibidos);
		containerMensajesEnviados = loadMensajesEnviados(mensajesEnviados);
		
		tableMessages.setContainerDataSource(containerMensajesRecibidos);
		tableMessages.setVisibleColumns(visiblecolsMensajesRecibidos);
		tableMessages.setSelectable(true);
		tableMessages.setImmediate(true);

	}

	private void initTable() {

		List<Monitor> monitores = mon.getAll();
		monitorData = loadData(monitores);

		tableContacts.setContainerDataSource(monitorData);
		tableContacts.setVisibleColumns(visibleCols);
		tableContacts.setSelectable(true);
		tableContacts.setImmediate(true);

		// listen for valueChange
		tableContacts.addListener(new Table.ValueChangeListener() {
			public void valueChange(ValueChangeEvent event) {

				correosSeleccionados.clear();

				Set<?> value = (Set<?>) event.getProperty().getValue();
				if (null == value || value.size() == 0) {

					getWindow().showNotification("No selection");
				} else {

					for (Iterator iter = value.iterator(); iter.hasNext();) {
						correosSeleccionados.add(monitorData
								.getItem(iter.next().hashCode())
								.getItemProperty("Email").toString());
						// System.out.println("Selected: " +
						// monitorData.getItem(iter.next().hashCode()).getItemProperty("Email"));
					}
				}

			}

		});

	}

	private static IndexedContainer loadMensajesRecibidos(List<Mensaje> c) {

		IndexedContainer ic = new IndexedContainer();

		for (String p : fieldMensajesRecibidos) {
			ic.addContainerProperty(p, String.class, "");
		}

		for (int i = 0; i < c.size(); ++i) {
			Object id = ic.addItem();

			// visible columns
			ic.getContainerProperty(id, "Asunto")
					.setValue(c.get(i).getAsunto());
			ic.getContainerProperty(id, "De").setValue(
					c.get(i).getEmisor().getNombre());
			ic.getContainerProperty(id, "Fecha enviado").setValue(
					c.get(i).getFechaEnviado());
			
			// no visible
			ic.getContainerProperty(id, "Contenido").setValue(
					c.get(i).getContenido());
			ic.getContainerProperty(id, "CorreoRemitente").setValue(
					c.get(i).getEmisor().getCorreo());

		}

		return ic;
	}

	private static IndexedContainer loadMensajesEnviados(List<Mensaje> c) {

		IndexedContainer ic = new IndexedContainer();

		for (String p : fieldMensajesEnviados) {
			ic.addContainerProperty(p, String.class, "");
		}

		for (int i = 0; i < c.size(); ++i) {
			Object id = ic.addItem();

			// visible columns
			ic.getContainerProperty(id, "Asunto")
					.setValue(c.get(i).getAsunto());
			ic.getContainerProperty(id, "Para").setValue(
					c.get(i).getReceptor().getNombre());
			ic.getContainerProperty(id, "Fecha enviado").setValue(
					c.get(i).getFechaEnviado());

			// no visible
			ic.getContainerProperty(id, "Contenido").setValue(
					c.get(i).getContenido());

		}

		return ic;
	}

	private static IndexedContainer loadData(List<Monitor> c) {

		IndexedContainer ic = new IndexedContainer();

		for (String p : fieldnames) {
			ic.addContainerProperty(p, String.class, "");
		}

		for (int i = 0; i < c.size(); ++i) {
			Object id = ic.addItem();

			// visible columns
			ic.getContainerProperty(id, "Nombre")
					.setValue(c.get(i).getNombre());
			ic.getContainerProperty(id, "Teléfono").setValue(
					c.get(i).getTelefono().toString());
			ic.getContainerProperty(id, "Ubicación").setValue(
					c.get(i).getUbicacion());
			ic.getContainerProperty(id, "Email").setValue(c.get(i).getCorreo());

		}

		return ic;
	}

	private void initFilteringControls() {

		for (final String pn : visibleCols) {
			final TextField txtSearch = new TextField();
			txtSearch.setImmediate(true);
			txtSearch.setWidth("100.0%");
			txtSearch.setHeight("-1px");
			txtSearch.setInputPrompt(pn);
			horizontalLayout_1.addComponent(txtSearch);
			horizontalLayout_1.setExpandRatio(txtSearch, 1.0f);

			txtSearch.addListener(new Property.ValueChangeListener() {
				public void valueChange(ValueChangeEvent event) {
					monitorData.removeContainerFilters(pn);
					if (txtSearch.toString().length() > 0
							&& !pn.equals(txtSearch.toString())) {
						monitorData.addContainerFilter(pn,
								txtSearch.toString(), true, false);
					}

				}
			});

		}
	}

	private GridLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new GridLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("100%");
		mainLayout.setHeight("800px");
		mainLayout.setMargin(true);
		mainLayout.setRows(7);

		// top-level component properties
		setWidth("100.0%");
		setHeight("800px");

		// lblMessage1
		lblMessage1 = new Label();
		lblMessage1.setImmediate(false);
		lblMessage1.setWidth("-1px");
		lblMessage1.setHeight("-1px");
		lblMessage1.setValue("Mensajes recibidos y enviados");
		mainLayout.addComponent(lblMessage1, 0, 0);
		mainLayout.setComponentAlignment(lblMessage1, new Alignment(48));

		// tableMessages
		tableMessages = new Table("Mensajes");
		tableMessages.setImmediate(false);
		tableMessages.setWidth("100.0%");
		tableMessages.setHeight("250px");

		mainLayout.addComponent(tableMessages, 0, 1);

		// gridLayout_2
		gridLayout_2 = buildGridLayout_2();
		mainLayout.addComponent(gridLayout_2, 0, 2);

		// lblMessages2
		lblMessages2 = new Label();
		lblMessages2.setImmediate(false);
		lblMessages2.setWidth("-1px");
		lblMessages2.setHeight("-1px");
		lblMessages2.setValue("Enviar mensaje");
		mainLayout.addComponent(lblMessages2, 0, 3);
		mainLayout.setComponentAlignment(lblMessages2, new Alignment(48));

		// tableContacts

		tableContacts = new Table("Monitores registrados");
		tableContacts.setImmediate(true);
		tableContacts.setWidth("100.0%");
		tableContacts.setHeight("250px");
		tableContacts.setMultiSelect(true);
		mainLayout.addComponent(tableContacts, 0, 4);

		// horizontalLayout_1
		horizontalLayout_1 = buildHorizontalLayout_1();
		mainLayout.addComponent(horizontalLayout_1, 0, 5);

		return mainLayout;
	}

	private GridLayout buildGridLayout_2() {
		// common part: create layout
		gridLayout_2 = new GridLayout();
		gridLayout_2.setImmediate(false);
		gridLayout_2.setWidth("100.0%");
		gridLayout_2.setHeight("75px");
		gridLayout_2.setMargin(false);
		gridLayout_2.setColumns(2);

		// optionMessages
		optionMessages = new OptionGroup();
		optionMessages.setCaption("Ver mensajes:");
		optionMessages.addItem("Recibidos");
		optionMessages.addItem("Enviados");
		optionMessages.select("Recibidos");
		optionMessages.setImmediate(true);
		optionMessages.addListener(this);

		optionMessages.setWidth("-1px");
		optionMessages.setHeight("50px");
		gridLayout_2.addComponent(optionMessages, 0, 0);
		gridLayout_2.setComponentAlignment(optionMessages, new Alignment(48));

		// btnMessages
		btnMessages = new Button();
		btnMessages.setCaption("Ver mensaje");
		btnMessages.setImmediate(true);
		btnMessages.setWidth("-1px");
		btnMessages.setHeight("-1px");

		btnMessages.addListener(new ClickListener() {

			@Override
			public void buttonClick(ClickEvent event) {
				
				if (null == tableMessages.getValue()) {
					getWindow().showNotification(
							"Por favor, seleccione al menos un mensaje.",
							Notification.TYPE_ERROR_MESSAGE);
					return;
				}

				if (optionMessages.getValue().toString().equals("Enviados")) {

					String contenido = containerMensajesEnviados
							.getItem(tableMessages.getValue().hashCode())
							.getItemProperty("Contenido").toString();

					String asunto = containerMensajesEnviados
							.getItem(tableMessages.getValue().hashCode())
							.getItemProperty("Asunto").toString();

					String destinatario = containerMensajesEnviados
							.getItem(tableMessages.getValue().hashCode())
							.getItemProperty("Para").toString();

					MensajesRecibidosEnviadosEst mensajeEnviado = new MensajesRecibidosEnviadosEst(
							destinatario, asunto, contenido, false);

					final Window ventanaMensaje = new Window("Mensaje enviado");

					ventanaMensaje.setSizeUndefined();
					ventanaMensaje.addComponent(mensajeEnviado);
					ventanaMensaje.setWidth("580px");
					ventanaMensaje.setHeight("-1px");

					ventanaMensaje.setModal(true);
					ventanaMensaje.setResizable(false);

					getApplication().getMainWindow().addWindow(ventanaMensaje);
					ventanaMensaje.setVisible(true);

				} else if (optionMessages.getValue().toString()
						.equals("Recibidos")) {

					String contenido = containerMensajesRecibidos
							.getItem(tableMessages.getValue().hashCode())
							.getItemProperty("Contenido").toString();

					String asunto = containerMensajesRecibidos
							.getItem(tableMessages.getValue().hashCode())
							.getItemProperty("Asunto").toString();

					String remitente = containerMensajesRecibidos
							.getItem(tableMessages.getValue().hashCode())
							.getItemProperty("De").toString();
					
					String correoRemitente = containerMensajesRecibidos
							.getItem(tableMessages.getValue().hashCode())
							.getItemProperty("CorreoRemitente").toString();

					MensajesRecibidosEnviadosEst mensajeRecibido = new MensajesRecibidosEnviadosEst(
							remitente, asunto, contenido, est, mon, mensajeDAO, correoRemitente, estudianteActual);

					final Window ventanaMensaje = new Window("Mensaje recibido");

					ventanaMensaje.setSizeUndefined();
					ventanaMensaje.addComponent(mensajeRecibido);
					ventanaMensaje.setWidth("580px");
					ventanaMensaje.setHeight("-1px");

					ventanaMensaje.setModal(true);
					ventanaMensaje.setResizable(false);

					getApplication().getMainWindow().addWindow(ventanaMensaje);
					ventanaMensaje.setVisible(true);
				}

			}
		});

		gridLayout_2.addComponent(btnMessages, 1, 0);
		gridLayout_2.setComponentAlignment(btnMessages, new Alignment(48));

		return gridLayout_2;
	}

	private HorizontalLayout buildHorizontalLayout_1() {
		// common part: create layout
		horizontalLayout_1 = new HorizontalLayout();
		horizontalLayout_1.setImmediate(false);
		horizontalLayout_1.setWidth("100.0%");
		horizontalLayout_1.setHeight("-1px");
		horizontalLayout_1.setMargin(false);

		// btnSend
		btnSend = new Button();
		btnSend.setCaption("Enviar");
		btnSend.setImmediate(true);
		btnSend.setWidth("-1px");
		btnSend.setHeight("25px");
		btnSend.addListener(new ClickListener() {

			@Override
			public void buttonClick(ClickEvent event) {
	
				EnviarMensaje();
				
			}
		});

		horizontalLayout_1.addComponent(btnSend);

		return horizontalLayout_1;
	}

	private void EnviarMensaje() {

		if (tableContacts.getValue().toString().equals("[]")) {
			getWindow()
					.showNotification(
							"Por favor, seleccione al menos un destinatario para enviar el mensaje.",
							Notification.TYPE_ERROR_MESSAGE);
			return;
		} else {
			System.out.println(tableContacts.getValue() == null);
			MensajeComponenteEstudiante mensajeComponente = new MensajeComponenteEstudiante(
					est, mon, mensajeDAO, correosSeleccionados,
					estudianteActual);

			final Window ventanaMensaje = new Window("Enviar Mensaje");

			ventanaMensaje.setSizeUndefined();
			ventanaMensaje.addComponent(mensajeComponente);
			ventanaMensaje.setWidth("580px");
			ventanaMensaje.setHeight("-1px");

			ventanaMensaje.setModal(true);
			ventanaMensaje.setResizable(false);

			getApplication().getMainWindow().addWindow(ventanaMensaje);
			ventanaMensaje.setVisible(true);
		}
	}

	@Override
	public void valueChange(ValueChangeEvent event) {
		
		// Actualizar la tabla de mensajes
		initTableMessages();

		if (event.getProperty().toString().equals("Recibidos")) {
			
			tableMessages.setContainerDataSource(containerMensajesRecibidos);
			tableMessages.setVisibleColumns(visiblecolsMensajesRecibidos);
		} else if (event.getProperty().toString().equals("Enviados")) {
			
			tableMessages.setContainerDataSource(containerMensajesEnviados);
			tableMessages.setVisibleColumns(visiblecolsMensajesEnviados);
		}

	}

}
